package com.nine.controller;

import com.nine.constant.RoomConstant;
import com.nine.entity.Content;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 模拟直播间弹幕
 */
@Slf4j
@RestController
public class LiveRoomController {

    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 某个用户（userId=12）进入直播间，获取直播间内容
     * http://localhost:8012/goRoom?roomId=100&userId=12
     *
     * @return
     */
    @GetMapping("/goRoom")
    public List<Content> goRoom(Integer roomId, Integer userId) {
        List<Content> list = new ArrayList<>();
        String key = RoomConstant.ROOM_KEY + roomId;
        // 进入房间，返回最新的前5条弹幕
        // 对应 redis 命令，ZREVRANGE room:100 0 4 WITHSCORES
        Set<ZSetOperations.TypedTuple<Content>> rang = redisTemplate.opsForZSet().reverseRangeWithScores(key, 0, 4);
        for (ZSetOperations.TypedTuple<Content> obj : rang) {
            list.add(obj.getValue());
            log.info("用户进入直播间获取最新的前5条弹幕：content：{}，score：{}", obj.getValue(), obj.getScore().longValue());
        }
        String userKey = RoomConstant.ROOM_USER_TIME_KEY + userId;
        // 当前的时间，存入到 redis，供下次拉取使用，看过的就不再推送
        long now = System.currentTimeMillis() / 1000;
        // 记录用户进入直播间的时间戳，对应 redis 命令，SET user:room:time:12 1679415660
        redisTemplate.opsForValue().set(userKey, now);
        return list;
    }

    /**
     * 登录房间之后，持续观看，定时任务或者xxl-job 客户端，每隔5s 来拉取数据
     * http://localhost:8012/commentList?roomId=100&userId=12
     *
     * @param roomId
     * @param userId
     * @return
     */
    @GetMapping("/commentList")
    public List<Content> commentList(Integer roomId, Integer userId) {
        List<Content> list = new ArrayList<>();
        String key = RoomConstant.ROOM_KEY + roomId;
        String userKey = RoomConstant.ROOM_USER_TIME_KEY + userId;
        // 当前的时间，存入到 redis，供下次拉取使用，看过的就不再推送
        long now = System.currentTimeMillis() / 1000;

        // 读取上次用户进入直播间的时间戳，对应 redis 命令，GET user:room:time:12
        Long ago = Long.parseLong(redisTemplate.opsForValue().get(userKey).toString());
        log.info("查找的时间范围：{} - {}", ago, now);

        // 对应 redis 命令，ZREVRANGE room:100 0 4 WITHSCORES
        Set<ZSetOperations.TypedTuple<Content>> rang = redisTemplate.opsForZSet().rangeByScore(key, ago, now);
        for (ZSetOperations.TypedTuple<Content> obj : rang) {
            list.add(obj.getValue());
            log.info("用户持续观看直播：content：{}，score：{}", obj.getValue(), obj.getScore().longValue());
        }
        // 重新获取当前的时间
        now = System.currentTimeMillis() / 1000;
        // 记录用户进入直播间的时间戳，对应 redis 命令，SET user:room:time:12 1679415660
        redisTemplate.opsForValue().set(userKey, now);
        return list;
    }

}
